﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Linq扩展方法
{
    internal class Program
    {
        static void Main(string[] args)
        {
            List<Employee> list = new List<Employee>();
            list.Add(new Employee { Id = 1, Name = "yyy", Age = 25, Gender = true, Salary = 150 });
            list.Add(new Employee { Id = 2, Name = "yrs", Age = 26, Gender = true, Salary = 190 });
            list.Add(new Employee { Id = 3, Name = "yes", Age = 45, Gender = false, Salary = 850 });
            list.Add(new Employee { Id = 4, Name = "y2a", Age = 55, Gender = true, Salary = 1200 });
            list.Add(new Employee { Id = 5, Name = "ysd", Age = 65, Gender = false, Salary = 1450 });
            list.Add(new Employee { Id = 6, Name = "yfc", Age = 25, Gender = true, Salary = 1544});
            list.Add(new Employee { Id = 7, Name = "ysf", Age = 25, Gender = false, Salary = 1588 });
            list.Add(new Employee { Id = 8, Name = "yey", Age = 65, Gender = true, Salary = 1544 });

            #region Where方法，数据过滤
            var lists =  list.Where(e => e.Age > 30);
            foreach (Employee e in lists)
            {
                Console.WriteLine(e);  
            }
            #endregion

            #region Count方法，数据条数
            var count = list.Count();
            var count1 = list.Count(e => e.Age > 30);
            var count2 = list.Where(e => e.Age > 30).Count();
            Console.WriteLine($"count:{count}");
            Console.WriteLine($"count1:{count1}");
            Console.WriteLine($"count2:{count2}");
            #endregion



            //Any方法，判断是否至少有一条满足条件的数据,返回true和false
            var any1 = list.Any(e => e.Salary > 30);
            var any2 = list.Where(e => e.Salary > 30).Any();
            Console.WriteLine(any1);
            Console.WriteLine(any2);

            //Single方法，有且只有一条满足要求的数据（没有数据或多条报错）
            var single = list.Single(e => e.Id == 1);
            Console.WriteLine(single);
            //下面报错，因为等于25不知有一条数据
            //var singleError = list.Single(e => e.Age == 25);
            //Console.WriteLine(singleError);

            //SingleOrDefault方法，最多只有一条满足要求的数据(没有数据不报错，返回null;有多条会报错)
            var singleordefault = list.SingleOrDefault(e => e.Age == 45);
            var singleordefault2 = list.SingleOrDefault(e => e.Age == 100);
            Console.WriteLine(singleordefault);
            Console.WriteLine(singleordefault2);


            //First方法，至少有一条，返回第一条
            var first = list.First(e => e.Age == 25);
            Console.WriteLine(first);

            //FirstOrDefault方法，返回第一条或者默认值(没有数据会返回null)
            var firstorfault = list.FirstOrDefault(e => e.Age == 100);
            Console.WriteLine(firstorfault);

            #region OrderBy、OrderByDescending方法，排序
            Console.WriteLine("------按照年龄正序排列------");
            var orderby = list.OrderBy(e => e.Age);
            foreach (var item in orderby)
            {
                Console.WriteLine(item);
            }

            Console.WriteLine("------按照工资倒序排列------");
            var orderbydescending = list.OrderByDescending(e => e.Salary);
            foreach (var item in orderbydescending)
            {
                Console.WriteLine(item);
            }

            int[] nums = new int[] { 1, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
            var num2 = nums.OrderBy(e => e);//简单数组也要传递lambda表达式进去
            foreach (var item in num2)
            {
                Console.WriteLine(item);
            }

            //随机排序
            Random random = new Random();
            var item2 = list.OrderBy(e => random.Next());
            //var item2 = list.OrderBy(e => Guid.NewGuid());
            foreach (var item in item2)
            {
                Console.WriteLine(item);
            }

            Console.WriteLine("------按照名字最后一个字母倒序排列------");
            var text = list.OrderByDescending(e => e.Name[e.Name.Length-1]);
            foreach (var item in text)
            {
                Console.WriteLine(item);
            }

            Console.WriteLine("------按照年龄相同后工资正序排列------");
            var t = list.OrderBy(e => e.Age).ThenBy(e=>e.Salary);
            foreach (var item in t)
            {
                Console.WriteLine(item);
            }
            #endregion


            //Skip方法，跳过n条数据；Take方法，获取n条数据
            Console.WriteLine("-----跳过3条数据获取2条数据-------");
            var item1 = list.Skip(3).Take(2);
            foreach (var item in item1)
            {
                Console.WriteLine(item);
            }

            Console.WriteLine("-----跳过3条数据-------");
            var item4 = list.Skip(3);
            foreach (var item in item4)
            {
                Console.WriteLine(item);
            }

            Console.WriteLine("-----获取3条数据-------");
            var item5 = list.Take(3);
            foreach (var item in item5)
            {
                Console.WriteLine(item);
            }

            //链式操作
            Console.WriteLine("-----根据年龄排序跳过1条获取2条-------");
            var item6 = list.OrderBy(e=>e.Age).Skip(1).Take(2);
            foreach (var item in item6)
            {
                Console.WriteLine(item);
            }


            #region 聚合函数
            //Max（最大值） Min（最小值） Avg（平均值） Sum（总和） Count（计数）
            Console.WriteLine("--------------Max------------------");
            var max = list.Max(e=>e.Age);
            Console.WriteLine(max);
            Console.WriteLine("--------------年龄大于10工资最高的-------------");
            var max1 = list.Where(e=>e.Age > 10).Max(e=>e.Salary);
            Console.WriteLine(max1);

            Console.WriteLine("--------------年龄大于50所有人的平均工资-------------");
            var avg = list.Where(e=>e.Age >50).Average(e=>e.Salary);
            Console.WriteLine(avg);

            #endregion


            #region groupby 组
            Console.WriteLine("-----------根据年龄分组，获取每组的数据-------------");
            var group =list.GroupBy(e=>e.Age);
            foreach (var item in group)
            {
                Console.WriteLine(item.Key);
                Console.WriteLine("最大工资" + item.Max(e=>e.Salary));
                foreach (var text1 in item)
                {
                    Console.WriteLine(text1);
                }
            }


            Console.WriteLine("-----------根据年龄分组，获取每组人数和最小年龄并获取每组的所有数据-------------");
            var group2 = list.GroupBy(e => e.Age);
            foreach (var item in group)
            {
                var age = item.Key;
                var count3 = item.Count();
                var minage = item.Min(e=>e.Age);
                Console.WriteLine($"年龄：{age},人数：{count3},最小年龄：{minage}");
                foreach (var item9 in item)
                {
                    Console.WriteLine(item9);
                }
            }
            #endregion

            #region select 投影/映射
            Console.WriteLine("-------select---------");
            var select = list.Select(e => new {e.Name,e.Age, xingbie = e.Gender? "男":"女" } );
            foreach(var item in select)
            {
                //string name = item.Name;
                //var age = item.Age;
                //var xingbie = item.xingbie;
                Console.WriteLine($"名字：{item.Name},年龄：{item.Age}, 性别：{item.xingbie }");
            }

            #endregion
            Console.WriteLine("---------------------");
            var tolist = list.Where(e=>e.Age>20).ToList();
            foreach (var item in tolist)
            {
                Console.WriteLine(item);
            }

            Console.WriteLine("---------------------");
            var toarray = list.Where(e => e.Age > 20).ToArray();
            foreach (var item in toarray)
            {
                Console.WriteLine(item);
            }

            var text2 = list.Where(e => e.Age > 2).GroupBy(e => e.Age).OrderBy(g => g.Key).Take(3).Select(g => new { nl = g.Key, rs = g.Count(), pj = g.Average(e => e.Salary) });
            foreach (var item in text2)
            {
                Console.WriteLine(item);
            }


            //有一个用逗号分割的表示成绩的字符串，如"55,44,55,44"，计算这些成绩的平均值
            string s = "55,44,55,55";
            var result = s.Split(',').Select(e => Convert.ToInt32(e)).Average();
            Console.WriteLine(result);


            //统计一个字符串中每个字母出现的频率（忽略大小写），然后按照从高到低的顺序输出出现频率高于2次的单词和其他出现的频率
            Console.WriteLine("///////////////");
            string s8 = "hrlll,hHhGhhhh,dsgsdjgfi";
            var result2 = s8.Where(c => char.IsLetter(c)).Select(c=>char.ToLower(c)).GroupBy(c => c).Select(g => new { g.Key, count = g.Count() }).OrderByDescending(g => g.count).Where(g => g.count > 2);
            foreach (var item in result2)
            {
                Console.WriteLine(item);
            }

            Console.ReadLine();
        }
    }
}
